package com.d3works.apps.businessproject.service;

import com.d3works.apps.account.db.Invoice;
import com.d3works.apps.account.db.InvoicePayment;
import com.d3works.apps.account.db.repo.InvoicePaymentRepository;
import com.d3works.apps.account.service.AccountManagementAccountService;
import com.d3works.apps.account.service.ReconcileService;
import com.d3works.apps.account.service.app.AppAccountService;
import com.d3works.apps.account.service.config.AccountConfigService;
import com.d3works.apps.account.service.invoice.InvoiceTermService;
import com.d3works.apps.account.service.move.MoveCreateService;
import com.d3works.apps.account.service.move.MoveToolService;
import com.d3works.apps.account.service.move.MoveValidateService;
import com.d3works.apps.account.service.moveline.MoveLineCreateService;
import com.d3works.apps.account.service.payment.PaymentModeService;
import com.d3works.apps.account.service.payment.invoice.payment.InvoicePaymentToolService;
import com.d3works.apps.bankpayment.service.bankorder.BankOrderCreateService;
import com.d3works.apps.bankpayment.service.bankorder.BankOrderService;
import com.d3works.apps.bankpayment.service.invoice.payment.InvoicePaymentValidateServiceBankPayImpl;
import com.d3works.apps.businessproject.db.InvoicingProject;
import com.d3works.apps.businessproject.db.repo.InvoicingProjectRepository;
import com.d3works.apps.project.db.ProjectTask;
import com.d3works.apps.project.db.repo.ProjectRepository;
import com.d3works.exception.D3worksException;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.google.inject.servlet.RequestScoped;
import java.io.IOException;
import javax.xml.bind.JAXBException;
import javax.xml.datatype.DatatypeConfigurationException;

@RequestScoped
public class InvoicePaymentValidateProjectServiceImpl
    extends InvoicePaymentValidateServiceBankPayImpl {

  private InvoicingProjectRepository invoicingProjectRepo;

  @Inject
  public InvoicePaymentValidateProjectServiceImpl(
      PaymentModeService paymentModeService,
      MoveCreateService moveCreateService,
      MoveValidateService moveValidateService,
      MoveToolService moveToolService,
      MoveLineCreateService moveLineCreateService,
      AccountConfigService accountConfigService,
      InvoicePaymentRepository invoicePaymentRepository,
      ReconcileService reconcileService,
      InvoicePaymentToolService invoicePaymentToolService,
      InvoiceTermService invoiceTermService,
      AppAccountService appAccountService,
      AccountManagementAccountService accountManagementAccountService,
      BankOrderCreateService bankOrderCreateService,
      BankOrderService bankOrderService,
      InvoicingProjectRepository invoicingProjectRepo) {
    super(
        paymentModeService,
        moveCreateService,
        moveValidateService,
        moveToolService,
        moveLineCreateService,
        accountConfigService,
        invoicePaymentRepository,
        reconcileService,
        invoicePaymentToolService,
        invoiceTermService,
        appAccountService,
        accountManagementAccountService,
        bankOrderCreateService,
        bankOrderService);
    this.invoicingProjectRepo = invoicingProjectRepo;
  }

  @Override
  @Transactional(rollbackOn = {Exception.class})
  public void validate(InvoicePayment invoicePayment, boolean force)
      throws D3worksException, JAXBException, IOException, DatatypeConfigurationException {
    super.validate(invoicePayment, force);
    Invoice invoice = invoicePayment.getInvoice();

    InvoicingProject invoicingProject =
        invoicingProjectRepo
            .all()
            .filter(
                "self.invoice.id = ?1 AND self.project.invoicingSequenceSelect = ?2",
                invoice.getId(),
                ProjectRepository.INVOICING_SEQ_INVOICE_PRE_TASK)
            .fetchOne();

    if (invoicingProject != null) {
      for (ProjectTask projectTask : invoicingProject.getProjectTaskSet()) {
        projectTask.setIsPaid(invoice.getHasPendingPayments());
      }
    }
  }
}
